package com.cskaoyan.javase.oop1._2reference;
/**
 * 回顾一下引用数据类型
 * 我们首先通过数组的学习,知道引用数据类型的实质:
 *      1.在栈上创建引用
 *      2.在堆上创建对象
 *      堆上的对象是实质,但是我们不能直接使用对象.栈上的引用通过获取堆上对象的地址去间接的操作堆上的对象
 *      但是这里理解引用数据类型有一个问题:
 *      基本数据类型和引用数据类型是完全割裂开的,没有任何联系
 * 我们需要重新认识引用数据类型,将它们的定义联系起来.
 * 数据类型的定义: 一组数据的集合和基于这组数据的合法操作.
 * 比如int类型,它有固定的取值范围,固定的取值,并且能够进行的操作也是固定的.
 *
 * 我们把引用数据类型(类)中定义的成员变量看成数据的集合
 * 而类中定义的成员方法,看成是基于这组数据的合法操作
 * 所以我们定义一个类,也是定义数据 + 操作
 * 所以类就是一种新的,自定义的,特殊的数据类型,称之为引用数据类型
 *
 * 当我们在程序中使用一个基本数据类型时，由于基本数据类型是JVM当中已经预先定义好的（所以基本数据类型叫"内置数据类型"），JVM可以清楚的知道这个基本数据类型变量在内存中的存储方式（占用空间大小、结构等等），JVM能够正常开辟空间，正常给变量初始化赋值。
 *
 * 但是引用数据类型并不是内置数据类型，而是我们自定义的数据类型，要想让JVM帮助我们开辟空间创建引用和对象，JVM怎么知道到底要创建什么呢？难道它未卜先知吗？
 *
 * 肯定不可能未卜先知,为了创建这个类的对象,JVM首先就需要了解这个类型,知道这个类的类型信息:
 *      比如该类中有哪些成员变量,哪些方法等等
 *
 * 在Java中,把jvm认识了解一个类型的过程,称之为"类加载"
 * 关于类加载:
 *      1.类加载的具体过程,我们后面会详细学习,这里我们先不用知道详细的概念.
 *      2.类加载是通过把某个类的二进制字节码文件(class文件)通过I/O流的形式,读取进JVM内存中的方法区实现的.(把U盘的内容拷贝进硬盘,这就是一种I/O,class文件也是存在硬盘中的,通过I/O读取进JVM内存,它的效率是很低的)
 *      3.JVM通过类加载,了解该类的类型信息,于是就可以开始创建这个类的对象了.
 *
 * 思考:
 *      1.类加载的顺序和创建对象的顺序谁先谁后?
 *          很明显要先类加载,然后JVM才能创建对象
 *      2.程序启动的时候,程序中会创建大量的对象,那么类加载是一股脑将会用到的类全部类加载
 *          还是等到需要用的时候类加载?
 *          类加载效率低,所以Java中类加载的设计原则是"懒加载"
 *          即,只有到非类加载不可,不类加载该类,程序就无法运行时,JVM才会类加载某个类
 *          这是为了保证程序的运行效率
 *
 *          在java中,我们把一定会类加载某个类的场景,称之为"类加载的时机"
 *          目前我们学习过的类加载的时机:
 *              1.new对象
 *              2.启动某个类的main方法,会触发该类的类加载,并且在启动main方法之前类加载
 *
 *      3.如果某个程序中,有多个触发类加载的时机,那么这个类可能类加载多次吗?
 *          某个类在程序的一次运行过程中,最多只会类加载一次
 *          某个类的类加载全局唯一
 *
 * @since 14:34
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    /*
        这样的一个main方法
        类加载了几个类?  两个
        顺序是什么样的?
            首先启动main方法,先触发Demo类的类加载,Demo类类加载结束后,才会启动main方法
            启动main方法后,要创建A类的对象
            会先去触发A类的类加载
            A类类加载结束后,才能够创建A类的对象
     */
    public static void main(String[] args) {
        A a = new A();
        /*
            Demo已经通过启动main方法触发了一次类加载
            后面虽然又创建了它的对象
            但已经不会再次类加载了.
         */
        Demo d = new Demo();
        A a2 = new A();
    }
}
class A{
    int age;
}
